use cursive::traits::Nameable;
use tokio::runtime::Runtime;
use cursive::{View, Cursive, CursiveExt};
use cursive::views::{Dialog,
                     TextView,
                     ListView,
                     ScrollView
                    };

pub mod port_mapper;
pub mod tui;
pub mod config_file;

fn _mapper_test() -> Result<(), Box<dyn std::error::Error>> {
    let rt = Runtime::new()?;
    rt.block_on(async {
        let (mapper, h) = port_mapper::Mapper::new("127.0.0.1", 8088,
                                                   "127.0.0.1", 8888);

        tokio::spawn(async move {
            println!("Sleep for 10s");
            tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
            println!("Wokeup! start to shutdown...");
            h.shutdown().await;
            println!("Shutdowned!")
        });

        match mapper.run().await {
            Ok(_) => {
                println!("mapper exist normally");
            },
            Err(e) => {
                println!("mapper run error: {:?}", e);
            }
        }
    });
    Ok(())
}

fn _build_main_dialog() -> impl View {
    let mut lst_view = ListView::new();

    for i in 1..100 {
        lst_view.add_child(&std::format!("item {}", i), TextView::new("text"));
    }

    let lst_view = ScrollView::new(lst_view);

    Dialog::new().title("XPortMapper")
                 .content(lst_view)
                 .with_name("main_dialog")
}

fn _cursive_test() -> Result<(), Box<dyn std::error::Error>> {
    let mut siv = Cursive::new();

    let screen = siv.screen_mut();
    screen.add_layer(_build_main_dialog());

    siv.run();
    Ok(())
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    tui::tui_run()
}
